﻿using UnityEngine;
using System.IO;
using UnityEditor;
using System.Text;
using System.Diagnostics;
using System.Xml;
using System.Collections.Generic;
using System;

namespace QPTools
{
    public class BuildTP : Editor
    {
        public static string UTPpath = string.Empty;
        public static void CreaterTexturePacker(string _path, int size)
        {
            UTPpath = _path;
            //选择并设置TP命令行的参数和参数值
            string commandText = " --sheet {0}.png --data {1}.xml --format sparrow --trim-mode None --pack-mode Best  --algorithm MaxRects --max-size " + size + " --size-constraints POT  --disable-rotation --scale 1 {2}";
            string inputPath = string.Format("{0}/" + UTPpath, Application.dataPath);//小图目录
            string outputPath = string.Format("{0}/" + UTPpath, Application.dataPath);//用TP打包好的图集存放目录
            if (!Directory.Exists(inputPath)) { UnityEngine.Debug.LogError("图片路径错误！");return;}
            string[] imagePath = Directory.GetDirectories(inputPath);
            for (int i = 0; i < imagePath.Length; i++)
            {
                //UnityEngine.Debug.Log(imagePath[i]);
                StringBuilder sb = new StringBuilder("");
                string[] fileName = Directory.GetFiles(imagePath[i]);
                for (int j = 0; j < fileName.Length; j++)
                {
                    string extenstion = Path.GetExtension(fileName[j]);
                    if (extenstion == ".png")
                    {
                        sb.Append(fileName[j]);
                        sb.Append("  ");
                    }
                }
                string name = Path.GetFileName(imagePath[i]);
                string outputName = string.Format("{0}/" + UTPpath + "/{1}/{2}", Application.dataPath, name, name);
                string sheetName = string.Format("{0}/" + UTPpath + "/{1}", Application.dataPath, name);
                //执行命令行
                processCommand("C:\\Program Files\\CodeAndWeb\\TexturePacker\\bin\\TexturePacker.exe", string.Format(commandText, sheetName, sheetName, sb.ToString()));
            }
            AssetDatabase.Refresh();
            BuildTexturePacker();
        }

        private static void processCommand(string command, string argument)
        {
            ProcessStartInfo start = new ProcessStartInfo(command);
            start.Arguments = argument;
            start.CreateNoWindow = false;
            start.ErrorDialog = true;
            start.UseShellExecute = false;

            if (start.UseShellExecute)
            {
                start.RedirectStandardOutput = false;
                start.RedirectStandardError = false;
                start.RedirectStandardInput = false;
            }
            else
            {
                start.RedirectStandardOutput = true;
                start.RedirectStandardError = true;
                start.RedirectStandardInput = true;
                start.StandardOutputEncoding = System.Text.UTF8Encoding.UTF8;
                start.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;
            }

            Process p = Process.Start(start);
            if (!start.UseShellExecute)
            {
                p.StandardOutput.ReadToEnd();
                p.StandardError.ReadToEnd();
            }

            p.WaitForExit();
            p.Close();
        }


        public static List<string> UnPath = new List<string>();
        // [MenuItem("Tools/SpritesPacker/TexturePacker")]
        public static void BuildTexturePacker()
        {
            string inputPath = string.Format("{0}/" + UTPpath + "/", Application.dataPath);
            string[] imagePath = Directory.GetFiles(inputPath);
            foreach (string v in imagePath)
            {
                if (Path.GetExtension(v) == ".png" || Path.GetExtension(v) == ".PNG")
                {
                    string sheetPath = GetAssetPath(v);
                    Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(sheetPath);
                    UnPath.Add((Application.dataPath + "/" + sheetPath).Replace("Assets/Assets", "Assets"));
                    string rootPath = string.Format("{0}/" + UTPpath + "/{1}", Application.dataPath, texture.name);
                    string pngPath = rootPath + "/" + texture.name + ".png";
                    TextureImporter asetImp = null;
                    Dictionary<string, Vector4> tIpterMap = new Dictionary<string, Vector4>();
                    if (Directory.Exists(rootPath))
                    {
                        if (File.Exists(pngPath))
                        {
                            UnityEngine.Debug.Log("exite: " + pngPath);
                            asetImp = GetTextureIpter(pngPath);
                            SaveBoreder(tIpterMap, asetImp);
                            File.Delete(pngPath);
                        }
                        File.Copy(inputPath + texture.name + ".png", pngPath);
                    }
                    else
                    {
                        Directory.CreateDirectory(rootPath);
                        File.Copy(inputPath + texture.name + ".png", pngPath);
                    }
                    AssetDatabase.Refresh();
                    string texturexml = inputPath + texture.name + ".xml";
                    UnPath.Add(texturexml);
                    FileStream fs = new FileStream(texturexml, FileMode.Open);
                    StreamReader sr = new StreamReader(fs);
                    string jText = sr.ReadToEnd();
                    fs.Close();
                    sr.Close();
                    XmlDocument xml = new XmlDocument();
                    xml.LoadXml(jText);
                    XmlNodeList elemList = xml.GetElementsByTagName("SubTexture");
                    WriteMeta(elemList, texture.name, tIpterMap);
                }
            }
            foreach (var item in BuildTP.UnPath)
            {
                if (File.Exists(item))
                {
                    File.Delete(item);
                }
            }
            AssetDatabase.Refresh();
        }
        //如果这张图集已经拉好了9宫格，需要先保存起来
        static void SaveBoreder(Dictionary<string, Vector4> tIpterMap, TextureImporter tIpter)
        {
            for (int i = 0, size = tIpter.spritesheet.Length; i < size; i++)
            {
                tIpterMap.Add(tIpter.spritesheet[i].name, tIpter.spritesheet[i].border);
            }
        }

        static TextureImporter GetTextureIpter(Texture2D texture)
        {
            TextureImporter textureIpter = null;
            string impPath = AssetDatabase.GetAssetPath(texture);
            textureIpter = TextureImporter.GetAtPath(impPath) as TextureImporter;
            return textureIpter;
        }

        static TextureImporter GetTextureIpter(string path)
        {
            TextureImporter textureIpter = null;
            Texture2D textureOrg = AssetDatabase.LoadAssetAtPath<Texture2D>(GetAssetPath(path));
            string impPath = AssetDatabase.GetAssetPath(textureOrg);
            textureIpter = TextureImporter.GetAtPath(impPath) as TextureImporter;
            return textureIpter;
        }
        //写信息到SpritesSheet里
        static void WriteMeta(XmlNodeList elemList, string sheetName, Dictionary<string, Vector4> borders)
        {
            string path = string.Format("Assets/" + UTPpath + "/{0}/{1}.png", sheetName, sheetName);
            Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
            string impPath = AssetDatabase.GetAssetPath(texture);
            TextureImporter asetImp = TextureImporter.GetAtPath(impPath) as TextureImporter;
            SpriteMetaData[] metaData = new SpriteMetaData[elemList.Count];
            for (int i = 0, size = elemList.Count; i < size; i++)
            {
                XmlElement node = (XmlElement)elemList.Item(i);
                Rect rect = new Rect();
                rect.x = int.Parse(node.GetAttribute("x"));
                rect.y = texture.height - int.Parse(node.GetAttribute("y")) - int.Parse(node.GetAttribute("height"));
                rect.width = int.Parse(node.GetAttribute("width"));
                rect.height = int.Parse(node.GetAttribute("height"));
                metaData[i].rect = rect;
                metaData[i].pivot = new Vector2(0.5f, 0.5f);
                metaData[i].name = node.GetAttribute("name");
                if (borders.ContainsKey(metaData[i].name))
                {
                    metaData[i].border = borders[metaData[i].name];
                }
            }
            asetImp.spritesheet = metaData;
            asetImp.textureType = TextureImporterType.Sprite;
            asetImp.spriteImportMode = SpriteImportMode.Multiple;
            asetImp.mipmapEnabled = false;
            asetImp.SaveAndReimport();
        }

        static string GetAssetPath(string path)
        {
            string[] seperator = { "Assets" };
            string p = "Assets" + path.Split(seperator, StringSplitOptions.RemoveEmptyEntries)[1];
            return p;
        }

    }

    //internal class TextureIpter
    //{
    //    public string spriteName = "";
    //    public Vector4 border = new Vector4();
    //    public TextureIpter() { }
    //    public TextureIpter(string spriteName, Vector4 border)
    //    {
    //        this.spriteName = spriteName;
    //        this.border = border;
    //    }
    //}
}